package com.hp.gxw.utils;

import cn.hutool.core.date.DateUnit;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;

public class DateUtil {

	// 默认日期格式
    public static final String DATE_DEFAULT_FORMAT = "yyyy-MM-dd";
    
    // 默认日期格式
    public static final String year_FORMAT = "yyyy";
    
 // 默认日期格式
    public static final String month_FORMAT = "MM";
    
    // 默认日期格式
    public static final String DATE_DEFAULT_FORMAT2 = "MM.dd";

    // 默认时间格式
    public static final String DATETIME_DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";

    // 默认时间格式
    public static final String DATETIME_SLASH_FORMAT = "yyyy/MM/dd HH:mm:ss";

    public static final String TIME_DEFAULT_FORMAT = "HH:mm:ss";

    // 日期格式化
    private static DateFormat dateFormat = null;

    // 时间格式化
    private static DateFormat dateTimeFormat = null;

    // 时间格式化
    private static DateFormat dateTimeSlashFormat = null;

    private static DateFormat timeFormat = null;

    private static Calendar gregorianCalendar = null;

    //上传间隔时间预留
    private static Integer before_hour = 12;

    static {
        dateFormat = new SimpleDateFormat(DATE_DEFAULT_FORMAT);
        dateTimeFormat = new SimpleDateFormat(DATETIME_DEFAULT_FORMAT);
        dateTimeSlashFormat = new SimpleDateFormat(DATETIME_SLASH_FORMAT);
        timeFormat = new SimpleDateFormat(TIME_DEFAULT_FORMAT);
        gregorianCalendar = new GregorianCalendar();
    }
    
    /**
     * 日期格式化yyyy-MM-dd
     * 
     * @param date
     * @return
     */
    public static Date formatDate(String date, String format) {
        try {
            return new SimpleDateFormat(format).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 日期格式化yyyy-MM-dd
     * 
     * @param date
     * @return
     */
    public static String getDateFormat(Date date) {
    	if(date == null) {
    		return null;
    	}
        return dateFormat.format(date);
    }

    /**
     * 当前日期前一天格式化yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getYesterdayFormat(Date date) {
    	if(date == null) {
    		return null;
    	}
        Calendar d = Calendar.getInstance();
    	d.setTime(date);
    	d.add(Calendar.DAY_OF_MONTH, -1);
        return dateFormat.format(d.getTime());
    }

    /**
     * 日期格式化yyyy-MM-dd
     * 
     * @param date
     * @return
     */
    public static String getDateFormat2(Date date) {
    	if(date == null) {
    		return null;
    	}
    	return new SimpleDateFormat(DATE_DEFAULT_FORMAT2).format(date);
    }

    /**
     * 日期格式化yyyy-MM-dd HH:mm:ss
     * 
     * @param date
     * @return
     */
    public static String getDateTimeFormat(Date date) {
        return dateTimeFormat.format(date);
    }

    /**
     * 时间格式化
     * 
     * @param date
     * @return HH:mm:ss
     */
    public static String getTimeFormat(Date date) {
        return timeFormat.format(date);
    }

    /**
     * 日期格式化
     * 
     * @param date
     * @param formatStr
     * @return
     */
    public static String getDateFormat(Date date, String formatStr) {
        if (StringUtils.isNotBlank(formatStr)) {
            return new SimpleDateFormat(formatStr).format(date);
        }
        return null;
    }

    /**
     * 日期格式化
     * 
     * @param date
     * @return
     */
    public static Date getDateFormat(String date) {
    	if(date==null||"".equals(date)){
    		 return null;
    	}
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 时间格式化
     * 
     * @param date
     * @return
     */
    public static Date getDateTimeFormat(String date) {
        try {
            return dateTimeFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 时间格式化
     *
     * @param date
     * @return
     */
    public static Date getDateTimeSlashFormat(String date) {
        try {
            return dateTimeSlashFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取当前日期(yyyy-MM-dd)
     * 
     * @param
     * @return
     */
    public static Date getNowDate() {
        return DateUtil.getDateFormat(dateFormat.format(new Date()));
    }
    
    /**
     * 根据日期获取年
     * @param date
     * @return
     */
    public static String getYearByDate(Date date) {
    	return new SimpleDateFormat(year_FORMAT).format(date);
    }

    /**
     * 根据日期获取年
     * @param date
     * @return
     */
    public static String getMonthByDate(Date date) {
    	return new SimpleDateFormat(month_FORMAT).format(date);
    }
    
    /**
     * 获取当前日期星期一日期
     * 
     * @return date
     */
    public static Date getFirstDayOfWeek() {
        gregorianCalendar.setFirstDayOfWeek(Calendar.MONDAY);
        gregorianCalendar.setTime(new Date());
        gregorianCalendar.set(Calendar.DAY_OF_WEEK, gregorianCalendar.getFirstDayOfWeek()); // Monday
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前日期星期日日期
     * 
     * @return date
     */
    public static Date getLastDayOfWeek() {
        gregorianCalendar.setFirstDayOfWeek(Calendar.MONDAY);
        gregorianCalendar.setTime(new Date());
        gregorianCalendar.set(Calendar.DAY_OF_WEEK, gregorianCalendar.getFirstDayOfWeek() + 6); // Monday
        return gregorianCalendar.getTime();
    }

    /**
     * 获取日期星期一日期
     * 
     * @param date
     * @return date
     */
    public static Date getFirstDayOfWeek(Date date) {
        if (date == null) {
            return null;
        }
        gregorianCalendar.setFirstDayOfWeek(Calendar.MONDAY);
        gregorianCalendar.setTime(date);
        gregorianCalendar.set(Calendar.DAY_OF_WEEK, gregorianCalendar.getFirstDayOfWeek()); // Monday
        return gregorianCalendar.getTime();
    }

    /**
     * 获取日期星期一日期
     * 
     * @param date
     * @return date
     */
    public static Date getLastDayOfWeek(Date date) {
        if (date == null) {
            return null;
        }
        gregorianCalendar.setFirstDayOfWeek(Calendar.MONDAY);
        gregorianCalendar.setTime(date);
        gregorianCalendar.set(Calendar.DAY_OF_WEEK, gregorianCalendar.getFirstDayOfWeek() + 6); // Monday
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前月的第一天
     * 
     * @return date
     */
    public static Date getFirstDayOfMonth() {
        gregorianCalendar.setTime(new Date());
        gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前月的第一天
     *
     * @return date
     */
    public static Date getFirstDayOfMonth(String month) {
        try {
            Date date = dateFormat.parse(month+"-01");
            gregorianCalendar.setTime(date);
            gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
        }catch (Exception e){
            e.printStackTrace();
        }
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前月的最后一天
     * 
     * @return
     */
    public static Date getLastDayOfMonth() {
        gregorianCalendar.setTime(new Date());
        gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
        gregorianCalendar.add(Calendar.MONTH, 1);
        gregorianCalendar.add(Calendar.DAY_OF_MONTH, -1);
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前月的最后一天
     *
     * @return
     */
    public static Date getLastDayOfMonth(String month) {
        try {
            Date date = dateFormat.parse(month+"-01");
            gregorianCalendar.setTime(date);
            gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
            gregorianCalendar.add(Calendar.MONTH, 1);
            gregorianCalendar.add(Calendar.DAY_OF_MONTH, -1);
        }catch (Exception e){
            e.printStackTrace();
        }
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前月的最后一天
     *
     * @return
     */
    public static String getLastDayOfMonthStr(String month) {
        try {
            Date date = dateFormat.parse(month+"-01");
            gregorianCalendar.setTime(date);
            gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
            gregorianCalendar.add(Calendar.MONTH, 1);
            gregorianCalendar.add(Calendar.DAY_OF_MONTH, -1);
        }catch (Exception e){
            e.printStackTrace();
        }
        return dateFormat.format(gregorianCalendar.getTime());
    }

    /**
     * 获取指定月的第一天
     * 
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        gregorianCalendar.setTime(date);
        gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
        return gregorianCalendar.getTime();
    }

    /**
     * 获取指定月的最后一天
     * 
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        gregorianCalendar.setTime(date);
        gregorianCalendar.set(Calendar.DAY_OF_MONTH, 1);
        gregorianCalendar.add(Calendar.MONTH, 1);
        gregorianCalendar.add(Calendar.DAY_OF_MONTH, -1);
        return gregorianCalendar.getTime();
    }

    /**
     * 获取日期前一天
     * 
     * @param date
     * @return
     */
    public static Date getDayBefore(Date date) {
        gregorianCalendar.setTime(date);
        int day = gregorianCalendar.get(Calendar.DATE);
        gregorianCalendar.set(Calendar.DATE, day - 1);
        return gregorianCalendar.getTime();
    }

    /**
     * 获取日期后一天
     * 
     * @param date
     * @return
     */
    public static Date getDayAfter(Date date) {
        gregorianCalendar.setTime(date);
        int day = gregorianCalendar.get(Calendar.DATE);
        gregorianCalendar.set(Calendar.DATE, day + 1);
        return gregorianCalendar.getTime();
    }

    /**
     * 获取当前年
     * 
     * @return
     */
    public static int getNowYear() {
        Calendar d = Calendar.getInstance();
        return d.get(Calendar.YEAR);
    }

    /**
     * 获取当前月份
     * 
     * @return
     */
    public static int getNowMonth() {
        Calendar d = Calendar.getInstance();
        return d.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当月天数
     * 
     * @return
     */
    public static int getNowMonthDay() {
        Calendar d = Calendar.getInstance();
        return d.getActualMaximum(Calendar.DATE);
    }

    /**
     * 获取时间段的每一天
     * 
     * @param endDate
     * @param startDate
     * @return 日期列表
     */
    public static List<Date> getEveryDayToDate(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return null;
        }
        // 格式化日期(yy-MM-dd)
        startDate = DateUtil.getDateFormat(DateUtil.getDateFormat(startDate));
        endDate = DateUtil.getDateFormat(DateUtil.getDateFormat(endDate));
        List<Date> dates = new ArrayList<Date>();
        gregorianCalendar.setTime(startDate);
        dates.add(gregorianCalendar.getTime());
        while (gregorianCalendar.getTime().compareTo(endDate) < 0) {
            // 加1天
            gregorianCalendar.add(Calendar.DAY_OF_MONTH, 1);
            dates.add(gregorianCalendar.getTime());
        }
        return dates;
    }
    
    /**
     * 获取时间段的每一天
     * 
     * @param startDate
     * @param endDate
     * @return 日期列表
     */
    public static List<String> getEveryDayToString(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return null;
        }
        // 格式化日期(yy-MM-dd)
        startDate = DateUtil.getDateFormat(DateUtil.getDateFormat(startDate));
        endDate = DateUtil.getDateFormat(DateUtil.getDateFormat(endDate));
        List<String> dates = new ArrayList<String>();
        gregorianCalendar.setTime(startDate);
        dates.add(getDateFormat(gregorianCalendar.getTime()));
        while (gregorianCalendar.getTime().compareTo(endDate) < 0) {
            // 加1天
            gregorianCalendar.add(Calendar.DAY_OF_MONTH, 1);
            dates.add(getDateFormat(gregorianCalendar.getTime()));
        }
        return dates;
    }

    /**
     * 获取提前多少个月
     * 
     * @param monty
     * @return
     */
    public static Date getFirstMonth(int monty) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -monty);
        return c.getTime();
    }

    /**
     * 获取提前多少个月
     *
     * @param day
     * @return
     */
    public static Date getDelayDayTime(int day) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, day);
        return c.getTime();
    }

    /**
     * 当前时间加1
     * @param date
     * @return
     */
    public static Date addOneSecond(Date date) {    
        Calendar calendar = Calendar.getInstance();    
        calendar.setTime(date);    
        calendar.add(Calendar.SECOND, 1);    
        return calendar.getTime();    
    } 
    
    //获得系统时间.
  	public static Date sysTime() {
  		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
  		Date date = cal.getTime();
  		return date;
  	}
  	
  	/**
  	 * 时间是否相等  只比较年月
  	 * @param d1
  	 * @param d2
  	 * @return
  	 */
  	public static boolean sameDate(Date d1, Date d2) {
        LocalDate localDate1 = ZonedDateTime.ofInstant(d1.toInstant(), ZoneId.systemDefault()).toLocalDate();
        LocalDate localDate2 = ZonedDateTime.ofInstant(d2.toInstant(), ZoneId.systemDefault()).toLocalDate();
        return (localDate1.getYear() == localDate2.getYear() && localDate1.getMonthValue() == localDate2.getMonthValue());
    }
  	

	//获得系统时间转换为：201915108.
	public static String sysTimeToString() {
		Calendar c = Calendar.getInstance();//可以对每个时间域单独修改
		String year = String.valueOf(c.get(Calendar.YEAR)); 
		String month = (c.get(Calendar.MONTH)+1)<10?"0"+(c.get(Calendar.MONTH)+1):String.valueOf(c.get(Calendar.MONTH)+1);
		String date = c.get(Calendar.DATE)<10?"0"+c.get(Calendar.DATE):String.valueOf(c.get(Calendar.DATE));
		String hour = c.get(Calendar.HOUR_OF_DAY)<10?"0"+c.get(Calendar.HOUR_OF_DAY):String.valueOf(c.get(Calendar.HOUR_OF_DAY));
		String minute = c.get(Calendar.MINUTE)<10?"0"+c.get(Calendar.MINUTE):String.valueOf(c.get(Calendar.MINUTE));
		String second = c.get(Calendar.SECOND)<10?"0"+c.get(Calendar.SECOND):String.valueOf(c.get(Calendar.SECOND));
        String milliSecond = String.valueOf(c.get(Calendar.MILLISECOND));
		return year+month+date+hour+minute+second+milliSecond;
	}
	
	public static String sysTimeToyyyymmdd() {
		Calendar c = Calendar.getInstance();//可以对每个时间域单独修改
		String year = String.valueOf(c.get(Calendar.YEAR)); 
		String month = String.valueOf((c.get(Calendar.MONTH)+1)<10?"0"+(c.get(Calendar.MONTH)+1):(c.get(Calendar.MONTH)+1)); 
		String date = String.valueOf(c.get(Calendar.DATE)); 
		return year+month+date;
	}
	
	public static String getSysTimeHour() {
		Calendar c = Calendar.getInstance();//可以对每个时间域单独修改
		try {
			c.setTime(dateTimeFormat.parse(dateTimeFormat.format(new Date())));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY)); 
		String minute = String.valueOf(c.get(Calendar.MINUTE)); 
		String second = String.valueOf(c.get(Calendar.SECOND)); 
		return hour+":"+minute+":"+second;
	}
	
	//传入时间转换为：201915108.
	public static String sysTimeToStringToT() {
        synchronized(DateUtil.class) {
            Calendar c = Calendar.getInstance();//可以对每个时间域单独修改
            try {
                c.setTime(dateTimeFormat.parse(dateTimeFormat.format(new Date())));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String year = String.valueOf(c.get(Calendar.YEAR));
            String month = String.valueOf(c.get(Calendar.MONTH) + 1);
            String date = String.valueOf(c.get(Calendar.DATE));
            String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));
            String minute = String.valueOf(c.get(Calendar.MINUTE));
            String second = String.valueOf(c.get(Calendar.SECOND));
            return year + "-" + (month.length() < 2 ? "0" + month : month) + "-" + (date.length() < 2 ? "0" + date : date) + "T" + (hour.length() < 2 ? "0" + hour : hour) + ":" + (minute.length() < 2 ? "0" + minute : minute) + ":" + (second.length() < 2 ? "0" + second : second);
        }
    }

	public static String currentYYMMDD() {
		Calendar c = Calendar.getInstance();
		c.setTime(new Date());
		c.add(Calendar.MONTH, 1);
		int year = c.get(Calendar.YEAR);
		return String.valueOf(year).substring(2)+(c.get(Calendar.MONTH)<10?"0"+c.get(Calendar.MONTH):c.get(Calendar.MONTH))
		+(c.get(Calendar.DAY_OF_MONTH)<10?"0"+c.get(Calendar.DAY_OF_MONTH):c.get(Calendar.DAY_OF_MONTH));
	}

    public static boolean isToday(String str) throws Exception{
  	    Date date = dateTimeFormat.parse(str);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(new Date());
        c2.add(Calendar.HOUR, -before_hour);
        Date date2 = c2.getTime();
        if(date.after(date2)){
            return true;
        }
        return false;
  	}

    public static String currentBc(){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        String year = String.valueOf(c.get(Calendar.YEAR));
        int month = c.get(Calendar.MONTH)+1;
        int day = c.get(Calendar.DAY_OF_MONTH);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        if(8<=hour && hour<20){
            return year+(month>10?month:"0"+month)+(day>10?day:"0"+day);
        }else{
            return year+(month>10?month:"0"+month)+(day>10?day:"0"+day);
        }
  	}

    //获取传递天的开始时间
    public static Timestamp getThisDayFirstTime(String strDate) {
        Date time = null;
        try {
            time = dateTimeFormat.parse(strDate+" 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        String nowTime = dateTimeFormat.format(c.getTime());
        Timestamp goodsC_date = Timestamp.valueOf(nowTime);//把时间转换
        return goodsC_date;
    }

    //获取传递天的最后时间
    public static Timestamp getThisDayEndTime(String strDate) {
        Date time = null;
        try {
            time = dateTimeFormat.parse(strDate+" 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        String nowTime = dateTimeFormat.format(c.getTime());
        Timestamp goodsC_date =Timestamp.valueOf(nowTime);//把时间转换
        return goodsC_date;
    }

    /**
     *  获取两个日期之间的所有日期 (年月日)
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<String> getBetweenDate(Date startTime, Date endTime){
        // 声明保存日期集合
        List<String> list = new ArrayList<String>();
        //用Calendar 进行日期比较判断
        Calendar calendar = Calendar.getInstance();
        while (startTime.getTime()<=endTime.getTime()){
            // 把日期添加到集合
            list.add(dateFormat.format(startTime));
            // 设置日期
            calendar.setTime(startTime);
            //把日期增加一天
            calendar.add(Calendar.DATE, 1);
            // 获取增加后的日期
            startTime=calendar.getTime();
        }
        return list;
    }

    public static void main(String[] args) throws Exception {

        System.out.println(getDelayDayTime(20));
    }

    public static BigDecimal between(Date startTime, Date endTime, DateUnit minute) {
        long between = cn.hutool.core.date.DateUtil.between(startTime, endTime, minute);
        return new BigDecimal(between);
    }
}